package com.amigo.online.provider.user.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.amigo.online.common.param.dto.pay.CardPayDto;
import com.amigo.online.common.param.dto.pay.IosPayDto;
import com.amigo.online.common.util.IosVerifyUtil;
import com.amigo.online.provider.user.exception.UserException;
import com.amigo.online.provider.user.mapper.PaymentRecordTblMapper;
import com.amigo.online.provider.user.model.entity.PaymentRecordTbl;
import com.amigo.online.provider.user.service.PayService;

import br.com.userede.erede.Environment;
import br.com.userede.erede.Store;
import br.com.userede.erede.Transaction;
import br.com.userede.erede.eRede;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import static com.amigo.online.provider.user.service.impl.VIPServiceImpl.genId;

import com.amigo.online.common.core.response.StatusCode;
import org.springframework.validation.annotation.Validated;

import java.sql.SQLException;
import java.sql.SQLIntegrityConstraintViolationException;

/**
 * @author pangdonghao
 * @version 1.0
 * @csdn https://blog.csdn.net/pangdongh
 * @createDate 2019/10/22 15:04
 */
@Slf4j
@Service
public class PayServiceImpl implements PayService {
    @Autowired
    PaymentRecordTblMapper paymentRecordTblMapper;
    @Value("${spring.profiles.active}")
    String profile;
    @Override
    @Transactional(isolation = Isolation.READ_COMMITTED,propagation = Propagation.REQUIRES_NEW)
    public JSONObject payWithCard(@Validated CardPayDto dto) {


        PaymentRecordTbl paymentRecordTbl = new PaymentRecordTbl();
        paymentRecordTbl.setId(dto.getPaymentId());
        paymentRecordTbl.setCommodityType(dto.getCommodityType());
        paymentRecordTbl.setInfo(dto.getInfo());
        paymentRecordTbl.setPayMoney(dto.getPayMoney());
        paymentRecordTbl.setCardNumber(dto.getCardNumber());
        paymentRecordTbl.setHolder(dto.getHolder());

        paymentRecordTbl.setPaymentMethod("银行卡");
        paymentRecordTblMapper.insertSelective(paymentRecordTbl);
        String errInfo = "";
        String errCode = "";
        boolean paySuccess = false;
        Long payTime = 0L;
        String transactionId = dto.getPaymentId();

        JSONObject result = new JSONObject();

        Store store = new Store("80749690", "b183a01cef7647349e952fb4b9c6f039", Environment.production());

        Transaction transaction = new Transaction(Integer.valueOf(String.valueOf(dto.getPayMoney())), dto.getPaymentId());
        try {
//            if(card.getCardType() == 1) {
            log.info("信用卡支付--->");
            log.info(dto.getCardNumber());
            log.info(dto.getPin());
            log.info(dto.getExpirationDate().split("/")[0]);
            log.info(dto.getExpirationDate().split("/")[1]);
            log.info(dto.getHolder());
            log.info("金额 -> "+dto.getPayMoney());
            log.info("订单号->"+dto.getPaymentId());
            transaction.creditCard(
                    dto.getCardNumber(),
                    dto.getPin(),
                    dto.getExpirationDate().split("/")[0],
                    dto.getExpirationDate().split("/")[1].length() == 2 ? "20" + dto.getExpirationDate().split("/")[1] : dto.getExpirationDate().split("/")[1],
                    dto.getHolder().trim()
            );
            transaction = (new eRede(store).create(transaction));
            if (transaction.getReturnCode().equals("00")) {
                paySuccess = true;
                transactionId = dto.getPaymentId();
                payTime = System.currentTimeMillis()/1000;
            }else {
                transactionId = dto.getPaymentId();
                payTime = System.currentTimeMillis()/1000;
            }
        } catch (Exception e) {
            log.info("支付失败");
            if(transaction != null) {
                log.info(transaction.getReturnCode());
            }
            e.printStackTrace();
            throw new UserException(StatusCode.PAY_ERROR);
        }catch(Throwable t) {
            log.info("支付失败");
            if(transaction != null) {
                log.info(transaction.getReturnCode());
            }
            t.printStackTrace();
            paySuccess = false;
            throw new UserException(StatusCode.PAY_ERROR);
        } finally {
            result.put("success", paySuccess);
            result.put("errInfo", errInfo);
            result.put("payTime", payTime);
            result.put("errCode", errCode);
            result.put("transactionId", transactionId);
            if(paySuccess == true)
                result.put("trade_status","success");
            else
                result.put("trade_status","failure");
        }
        return result;
    }

    @Override
    @Transactional(isolation = Isolation.READ_COMMITTED,propagation = Propagation.REQUIRES_NEW)
    public String payWithIOS(@Validated IosPayDto dto) {
        String product_id;
        String json = IosVerifyUtil.buyAppVerify(dto.getBase64(),"dev".equals(profile) ? 0:1);
        JSONObject jsonObject = JSON.parseObject(json);
        if(jsonObject.getInteger("status") == 0 ){
            JSONArray jsonArray = jsonObject.getJSONObject("receipt").getJSONArray("in_app");
            String transaction_id = jsonArray.getJSONObject(jsonArray.size()-1).getString("transaction_id");
            product_id = jsonArray.getJSONObject(jsonArray.size()-1).getString("product_id");


            PaymentRecordTbl paymentRecordTbl = new PaymentRecordTbl();
            paymentRecordTbl.setId(genId());
            paymentRecordTbl.setCommodityType(dto.getCommodityType());
            paymentRecordTbl.setInfo(dto.getInfo());
            paymentRecordTbl.setExternalId(transaction_id);
            paymentRecordTbl.setPaymentMethod("IOS");
            try {
                paymentRecordTblMapper.insertSelective(paymentRecordTbl);
            }catch (Exception e){
                log.info("插入支付信息失败: " ,e);

                if(e instanceof  SQLIntegrityConstraintViolationException){
                    throw new UserException(StatusCode.TRANSACTION_ID_REPEAT);
                }else {
                    throw new UserException(StatusCode.PAY_ERROR);
                }
            }
        }else {
            throw new UserException(StatusCode.PAY_ERROR);
        }
        return product_id;
    }
}
